home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
akcl1615.lha
/
c
/
saveaix3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-13
|
7KB
|
269 lines
/*
(c) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
Copying of this file is authorized to users who have executed the true and
proper "License Agreement for Kyoto Common LISP" with SIGLISP.
(c) Copyright William F. Schelter.
*/
/*
unixsave.c
*/
#ifndef UNIX
#include "include.h"
#endif
#include <fcntl.h>
#include <filehdr.h>
#include <aouthdr.h>
#include <scnhdr.h>
filecpy(to, from, n)
FILE *to, *from;
register int n;
{
char buffer[BUFSIZ];
for (;;)
if (n > BUFSIZ) {
fread(buffer, BUFSIZ, 1, from);
fwrite(buffer, BUFSIZ, 1, to);
n -= BUFSIZ;
}
else if (n > 0) {
fread(buffer, 1, n, from);
fwrite(buffer, 1, n, to);
break;
}
else
break;
}
#include <sys/ldr.h>
#include <loader.h>
char *__start;
memory_save(original_file, save_file)
char *original_file, *save_file;
{ /* MEM_SAVE_LOCALS; */
struct filehdr Eheader;
struct aouthdr header;
struct scnhdr shdrs[15];
int stsize;
int textsize=0;
int after_data;
int orig_data_scnptr;
int orig_debug_scnptr;
char *data_begin, *data_end;
int original_data;
FILE *original, *save;
register int n;
register char *p;
extern char *sbrk();
extern char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ];
fclose(stdin);
original = fopen(original_file, "r");
if (stdin != original || original->_file != 0) {
fprintf(stderr, "Can't open the original file.\n");
exit(1);
}
setbuf(original, stdin_buf);
fclose(stdout);
unlink(save_file);
n = open(save_file, O_CREAT|O_WRONLY, 0777);
if (n != 1 || (save = fdopen(n, "w")) != stdout) {
fprintf(stderr, "Can't open the save file.\n");
exit(1);
}
setbuf(save, stdout_buf);
/* READ_HEADER; */
fread(&Eheader, sizeof(Eheader), 1, original);
fread(&header, sizeof(header), 1, original);
data_begin= 0x20000800;
{
char buf[500];
struct ld_info * ld;
loadquery(L_GETINFO,buf,sizeof(buf));
ld = (struct ld_info *)buf;
data_begin = ld->ldinfo_dataorg ;
}
/* header.data_start = data_begin; */
data_end = core_end;
original_data = header.dsize;
header.dsize = data_end - data_begin;
header.bsize = 0;
{
int j,i = Eheader.f_nscns;
int diff;
fread(shdrs +1 ,i,sizeof(struct scnhdr),original);
orig_data_scnptr = shdrs[header.o_sndata].s_scnptr;
orig_debug_scnptr = shdrs[8].s_scnptr;
diff = header.a_data - original_data
- shdrs[header.o_snbss + 1].s_size;
after_data = shdrs[header.o_snbss +2].s_scnptr;
Eheader.f_symptr += diff;
fwrite(&Eheader, sizeof(Eheader), 1, save);
fwrite(&header, sizeof(header), 1, save);
shdrs[header.o_snbss ].s_size = 0;
shdrs[header.o_snbss +1 ].s_size = 0;
/* ex**pect no more than 15 sections, and pad after data */
if (strcmp(".pad",shdrs[header.o_snbss + 1].s_name)
|| i >= 15)
perror("unexpected format of object file");
shdrs[header.o_sndata ].s_size = header.a_data;
/* shdrs[header.o_sndata].s_paddr = data_begin;
shdrs[header.o_sndata].s_vaddr = data_begin;
*/
for (j=1; j<= i; j++)
#define ADJUST(x) if(x) (x) = (x) + diff
{
ADJUST(shdrs[j].s_lnnoptr);
ADJUST(shdrs[j].s_relptr);
}
for (j= header.o_sndata +1 ; j<= i; j++)
{
ADJUST(shdrs[j].s_scnptr);
ADJUST(shdrs[j].s_vaddr);
ADJUST(shdrs[j].s_paddr);
}
fwrite(shdrs +1 ,i,sizeof(struct scnhdr),save);
/* FILECPY_HEADER; */
filecpy(save, original,
shdrs[header.o_sndata].s_scnptr
- sizeof(header)-sizeof(Eheader) - i*sizeof(struct scnhdr));
j= ftell(save);
j= ftell(original);
for (n = header.a_data, p = data_begin; ; n -= BUFSIZ, p += BUFSIZ)
if (n > BUFSIZ)
fwrite(p, BUFSIZ, 1, save);
else if (n > 0) {
fwrite(p, 1, n, save);
break;
}
else
break;
fseek(original, original_data, 1);
fseek(original, after_data, 0);
/* now positioned at the loader section */
{
struct ldhdr *ldheader;
struct ldrel * ldreloc_info,*p;
char *space;
space = (char *) sbrk(shdrs[header.o_snloader].s_size + 0x2000);
ldheader = (struct ldhdr *) space;
fread(space,1,shdrs[header.o_snloader].s_size,original);
ldreloc_info = (struct ldrel *)
(space + sizeof(struct ldhdr) + LDSYMSZ * ldheader->l_nsyms);
i = sizeof(struct ldhdr) + LDSYMSZ * (ldheader->l_nsyms);
for(p=ldreloc_info,i=0; i< ldheader->l_nreloc ; i++,p++)
{
if (p->l_rsecnm == header.o_snbss)
(p->l_rsecnm = header.o_sndata);
if (p->l_symndx == 2) /* make bss be data */
(p->l_symndx = 1);
}
/* p->l_vaddr += data_begin; */
fwrite(ldheader, 1, shdrs[header.o_snloader].s_size,save);
/* unrelocate */
{
int j1 = ftell(save);
int j2= ftell(original);
int off=0;
fseek(original,orig_data_scnptr,0);
fseek(save,shdrs[header.o_sndata].s_scnptr,0);
for(p=ldreloc_info,i=0; i< ldheader->l_nreloc ; i++,p++)
if (p->l_rsecnm == header.o_sndata)
{
int x,pos1,y;
int d = p->l_vaddr - off;
if (d)
{
fseek(save,d,1);
fseek(original,d,1);
off += d;
}
pos1 = ftell(original);
pos1 = ftell(save);
fread(&x,1,sizeof(int),original);
y = x;
if (p->l_symndx ==0)
{
int w = *((int *)&__start);
x = ((*(int *)(data_begin+off)));
x = x + header.text_start ;
x = x - w ;
}
if (p->l_symndx ==1 || p->l_symndx ==2)
{
x = ((*(int *)(data_begin + off)) - (int) data_begin);
}
fwrite(&x,1,sizeof(int),save);
off += sizeof(int);
}
fseek(save,j1,0);
fseek(original,j2,0);
}
}
sbrk(- (shdrs[header.o_snloader].s_size+ 0x2000));
filecpy(save,original,Eheader.f_symptr - ftell(save));
/* now at the beginning of the sym table */
{
struct syment symbol;
struct syment *sym = &symbol;
int naux;
int nsyms = Eheader.f_nsyms;
while (--nsyms >= 0)
{
fread(&symbol,1,SYMESZ,original);
fwrite(&symbol,1,SYMESZ,save);
naux= sym->n_numaux;
nsyms = nsyms - naux;
if (ISFCN(sym->n_type)
&& (naux >= 2))
{
fread(&symbol,1,SYMESZ,original);
(((union auxent *)(sym))->x_sym.x_fcnary.x_fcn.x_lnnoptr) += diff;
fwrite(&symbol,1,SYMESZ,save);
filecpy(save,original,SYMESZ*(naux -1));
}
else
filecpy(save,original,SYMESZ*(naux));
}
}
COPY_TO_SAVE;
fclose(original);
fclose(save);
}
}
Lsave()
{
char filename[256];
check_arg(1);
check_type_or_pathname_string_symbol_stream(&vs_base[0]);
coerce_to_filename(vs_base[0], filename);
_cleanup();
/*
{
FILE *p;
int nfile;
nfile = NUMBER_OPEN_FILES;
for (p = &_iob[3]; p < &_iob[nfile]; p++)
fclose(p);
}
*/
memory_save(kcl_self, filename);
_exit(0);
/*
exit(0);
*/
/* no return */
}